// Copyright(c) 2011 Matthew McMullan, Jorel Lalicki and Mike Heise, Jorel Lalicki and Mike Heise. See copying.txt for details.

#ifndef __agml_angles_h__
#define __agml_angles_h__

// make sure that this file is never included directly
#ifndef __agml_agml_h__
#error "Include AGML from agml.h only. This file is not a valid entry point for the library."
#endif

namespace agml {
	namespace _const {
		const _v128 __d2r = {(f32)_d2r,(f32) _d2r,(f32) _d2r,(f32) _d2r};
		const _v128 __d2g = {(f32)_d2g,(f32) _d2g,(f32) _d2g,(f32) _d2g};
		const _v128 __d2h = {(f32)_d2h,(f32) _d2h,(f32) _d2h,(f32) _d2h};
		const _v128 __d2t = {(f32)_d2t,(f32) _d2t,(f32) _d2t,(f32) _d2t};
		const _v128 __r2d = {(f32)_r2d,(f32) _r2d,(f32) _r2d,(f32) _r2d};
		const _v128 __r2g = {(f32)_r2g,(f32) _r2g,(f32) _r2g,(f32) _r2g};
		const _v128 __r2h = {(f32)_r2h,(f32) _r2h,(f32) _r2h,(f32) _r2h};
		const _v128 __r2t = {(f32)_r2t,(f32) _r2t,(f32) _r2t,(f32) _r2t};
		const _v128 __h2d = {(f32)_h2d,(f32) _h2d,(f32) _h2d,(f32) _h2d};
		const _v128 __h2r = {(f32)_h2r,(f32) _h2r,(f32) _h2r,(f32) _h2r};
		const _v128 __h2g = {(f32)_h2g,(f32) _h2g,(f32) _h2g,(f32) _h2g};
		const _v128 __h2t = {(f32)_h2t,(f32) _h2t,(f32) _h2t,(f32) _h2t};
		const _v128 __g2d = {(f32)_g2d,(f32) _g2d,(f32) _g2d,(f32) _g2d};
		const _v128 __g2r = {(f32)_g2r,(f32) _g2r,(f32) _g2r,(f32) _g2r};
		const _v128 __g2h = {(f32)_g2h,(f32) _g2h,(f32) _g2h,(f32) _g2h};
		const _v128 __g2t = {(f32)_g2t,(f32) _g2t,(f32) _g2t,(f32) _g2t};
		const _v128 __t2d = {(f32)_t2d,(f32) _t2d,(f32) _t2d,(f32) _t2d};
		const _v128 __t2r = {(f32)_t2r,(f32) _t2r,(f32) _t2r,(f32) _t2r};
		const _v128 __t2g = {(f32)_t2g,(f32) _t2g,(f32) _t2g,(f32) _t2g};
		const _v128 __t2h = {(f32)_t2h,(f32) _t2h,(f32) _t2h,(f32) _t2h};
	};
	super_inline f32 RadToRad(f32 angle) {
		return angle*_d2r;
	}
	void RadToRad(_v128 *source, _v128 *dest, u32 num) {
		while (num>0) {
			*dest = _mm_mul_ps(*source,_const::__d2r);
			dest+=1;
			source+=1;
			num--;
		}
	}
	template<u32 Size> super_inline void RadToRad(vstatic<f32,Size> &source, vstatic<f32,Size> &dest) {
		RadToRad(source.simd,dest.simd,(Size+3)/4);
	}
	super_inline f32 RadToGra(f32 angle) {
		return angle*_d2g;
	}
	void RadToGra(_v128 *source, _v128 *dest, u32 num) {
		while (num>0) {
			*dest = _mm_mul_ps(*source,_const::__d2g);
			dest+=1;
			source+=1;
			num--;
		}
	}
	template<u32 Size> super_inline void RadToGra(vstatic<f32,Size> &source, vstatic<f32,Size> &dest) {
		RadToGra(source.simd,dest.simd,(Size+3)/4);
	}
	super_inline f32 RadToHou(f32 angle) {
		return angle*_d2h;
	}
	void RadToHou(_v128 *source, _v128 *dest, u32 num) {
		while (num>0) {
			*dest = _mm_mul_ps(*source,_const::__d2h);
			dest+=1;
			source+=1;
			num--;
		}
	}
	template<u32 Size> super_inline void RadToHou(vstatic<f32,Size> &source, vstatic<f32,Size> &dest) {
		RadToHou(source.simd,dest.simd,(Size+3)/4);
	}
	super_inline f32 RadToTur(f32 angle) {
		return angle*_d2t;
	}
	void RadToTou(_v128 *source, _v128 *dest, u32 num) {
		while (num>0) {
			*dest = _mm_mul_ps(*source,_const::__d2t);
			dest+=1;
			source+=1;
			num--;
		}
	}
	template<u32 Size> super_inline void RadToTou(vstatic<f32,Size> &source, vstatic<f32,Size> &dest) {
		RadToTou(source.simd,dest.simd,(Size+3)/4);
	}
	super_inline f32 radToRad(f32 angle) {
		return angle*_r2d;
	}
	void radToRad(_v128 *source, _v128 *dest, u32 num) {
		while (num>0) {
			*dest = _mm_mul_ps(*source,_const::__r2d);
			dest+=1;
			source+=1;
			num--;
		}
	}
	template<u32 Size> super_inline void radToRad(vstatic<f32,Size> &source, vstatic<f32,Size> &dest) {
		radToRad(source.simd,dest.simd,(Size+3)/4);
	}
	super_inline f32 radToGra(f32 angle) {
		return angle*_r2g;
	}
	void radToGra(_v128 *source, _v128 *dest, u32 num) {
		while (num>0) {
			*dest = _mm_mul_ps(*source,_const::__d2g);
			dest+=1;
			source+=1;
			num--;
		}
	}
	template<u32 Size> super_inline void radToGra(vstatic<f32,Size> &source, vstatic<f32,Size> &dest) {
		radToGra(source.simd,dest.simd,(Size+3)/4);
	}
	super_inline f32 radToHou(f32 angle) {
		return angle*_r2h;
	}
	void radToHou(_v128 *source, _v128 *dest, u32 num) {
		while (num>0) {
			*dest = _mm_mul_ps(*source,_const::__d2h);
			dest+=1;
			source+=1;
			num--;
		}
	}
	template<u32 Size> super_inline void radToHou(vstatic<f32,Size> &source, vstatic<f32,Size> &dest) {
		radToHou(source.simd,dest.simd,(Size+3)/4);
	}
	super_inline f32 radToTur(f32 angle) {
		return angle*_r2t;
	}
	void radToTur(_v128 *source, _v128 *dest, u32 num) {
		while (num>0) {
			*dest = _mm_mul_ps(*source,_const::__d2t);
			dest+=1;
			source+=1;
			num--;
		}
	}
	template<u32 Size> super_inline void radToTur(vstatic<f32,Size> &source, vstatic<f32,Size> &dest) {
		radToTur(source.simd,dest.simd,(Size+3)/4);
	}
	super_inline f32 graToDeg(f32 angle) {
		return angle*_g2d;
	}
	void graToDeg(_v128 *source, _v128 *dest, u32 num) {
		while (num>0) {
			*dest = _mm_mul_ps(*source,_const::__g2d);
			dest+=1;
			source+=1;
			num--;
		}
	}
	template<u32 Size> super_inline void graToDeg(vstatic<f32,Size> &source, vstatic<f32,Size> &dest) {
		graToDeg(source.simd,dest.simd,(Size+3)/4);
	}
	super_inline f32 graToRad(f32 angle) {
		return angle*_g2r;
	}
	void graToRad(_v128 *source, _v128 *dest, u32 num) {
		while (num>0) {
			*dest = _mm_mul_ps(*source,_const::__g2r);
			dest+=1;
			source+=1;
			num--;
		}
	}
	template<u32 Size> super_inline void graToRad(vstatic<f32,Size> &source, vstatic<f32,Size> &dest) {
		graToRad(source.simd,dest.simd,(Size+3)/4);
	}
	super_inline f32 graToHou(f32 angle) {
		return angle*_g2h;
	}
	void graToHou(_v128 *source, _v128 *dest, u32 num) {
		while (num>0) {
			*dest = _mm_mul_ps(*source,_const::__g2h);
			dest+=1;
			source+=1;
			num--;
		}
	}
	template<u32 Size> super_inline void graToHou(vstatic<f32,Size> &source, vstatic<f32,Size> &dest) {
		graToHou(source.simd,dest.simd,(Size+3)/4);
	}
	super_inline f32 graToTur(f32 angle) {
		return angle*_g2t;
	}
	void graToTur(_v128 *source, _v128 *dest, u32 num) {
		while (num>0) {
			*dest = _mm_mul_ps(*source,_const::__g2t);
			dest+=1;
			source+=1;
			num--;
		}
	}
	template<u32 Size> super_inline void graToTur(vstatic<f32,Size> &source, vstatic<f32,Size> &dest) {
		graToTur(source.simd,dest.simd,(Size+3)/4);
	}
	super_inline f32 houToDeg(f32 angle) {
		return angle*_h2d;
	}
	void houToDeg(_v128 *source, _v128 *dest, u32 num) {
		while (num>0) {
			*dest = _mm_mul_ps(*source,_const::__h2d);
			dest+=1;
			source+=1;
			num--;
		}
	}
	template<u32 Size> super_inline void houToDeg(vstatic<f32,Size> &source, vstatic<f32,Size> &dest) {
		houToDeg(source.simd,dest.simd,(Size+3)/4);
	}
	super_inline f32 houToRad(f32 angle) {
		return angle*_h2r;
	}
	void houToRad(_v128 *source, _v128 *dest, u32 num) {
		while (num>0) {
			*dest = _mm_mul_ps(*source,_const::__h2r);
			dest+=1;
			source+=1;
			num--;
		}
	}
	template<u32 Size> super_inline void houToRad(vstatic<f32,Size> &source, vstatic<f32,Size> &dest) {
		houToRad(source.simd,dest.simd,(Size+3)/4);
	}
	super_inline f32 houToGra(f32 angle) {
		return angle*_h2g;
	}
	void houToGra(_v128 *source, _v128 *dest, u32 num) {
		while (num>0) {
			*dest = _mm_mul_ps(*source,_const::__h2g);
			dest+=1;
			source+=1;
			num--;
		}
	}
	template<u32 Size> super_inline void houToGra(vstatic<f32,Size> &source, vstatic<f32,Size> &dest) {
		houToGra(source.simd,dest.simd,(Size+3)/4);
	}
	super_inline f32 houToTur(f32 angle) {
		return angle*_h2t;
	}
	void houToTur(_v128 *source, _v128 *dest, u32 num) {
		while (num>0) {
			*dest = _mm_mul_ps(*source,_const::__h2t);
			dest+=1;
			source+=1;
			num--;
		}
	}
	template<u32 Size> super_inline void houToTur(vstatic<f32,Size> &source, vstatic<f32,Size> &dest) {
		houToTur(source.simd,dest.simd,(Size+3)/4);
	}
}
#endif
